package com.dtp.core.handler;

import com.dtp.common.entity.ThreadPoolStats;
import com.dtp.core.monitor.collector.InternalLogCollector;
import com.dtp.core.monitor.collector.LogCollector;
import com.dtp.core.monitor.collector.MetricsCollector;
import com.dtp.core.monitor.collector.MicroMeterCollector;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

/**
 * 指标信息收集器处理类
 *
 * @author yanhom
 * @since 1.0.0
 *
 * @remark muse
 **/
@Slf4j
public final class CollectorHandler {

    private static final Map<String, MetricsCollector> COLLECTORS = Maps.newHashMap(); // 指标收集器缓存类

    private CollectorHandler() {
        // 通过SPI，加载MetricsCollector的实现类，并保存到COLLECTORS中
        ServiceLoader<MetricsCollector> loader = ServiceLoader.load(MetricsCollector.class);
        for (MetricsCollector collector : loader) COLLECTORS.put(collector.type(), collector);

        // 默认情况下，会初始化3种指标收集器，分别是MetricsCollector、LogCollector和InternalLogCollector
        MetricsCollector microMeterCollector = new MicroMeterCollector();
        LogCollector logCollector = new LogCollector();
        InternalLogCollector internalLogCollector = new InternalLogCollector();
        COLLECTORS.put(microMeterCollector.type(), microMeterCollector);
        COLLECTORS.put(logCollector.type(), logCollector);
        COLLECTORS.put(internalLogCollector.type(), internalLogCollector);
    }

    /** 针对ThreadPoolStats执行收集执操作 */
    public void collect(ThreadPoolStats poolStats, List<String> types) {
        if (poolStats == null || CollectionUtils.isEmpty(types)) return;

        for (String collectorType : types) {
            MetricsCollector collector = COLLECTORS.get(collectorType.toLowerCase());
            if (collector != null) collector.collect(poolStats); // 行收集执操作
        }
    }

    /** 获得单例 */
    public static CollectorHandler getInstance() {return CollectorHandlerHolder.INSTANCE; }
    private static class CollectorHandlerHolder {
        private static final CollectorHandler INSTANCE = new CollectorHandler();
    }
}
